
#include "../../Command.h"

#include "../../User.h"
#include "../../NLogic/Static.h"
#include "../../NLogic/Stamina.h"
#include "../../NLogic/VirtualCurrency.h"
#include "../../NResource/Static.h"

namespace ProjectZ { namespace NCommand {

static void SendAckDungeonCreateSingleV2(User * pUser, int ack)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << static_cast<int16_t>(ack);
	pAck->MakePacket(CMD_SC_REQ_DUNGEON_CREATE_SINGLE_V2);
	pUser->Send(pAck);
}

void Command::CS_REQ_DUNGEON_CREATE_SINGLE_V2(User * pUser, ::Network::Packet *pPacket)
{
	/*
	 * /// 솔로 플레이
	CS_REQ_DUNGEON_CREATE_SINGLE_V2      0x1136
	{
			   u16 u16dungeon_tid;                //추가됨
			   u8 u8difficulty;
			   u8 u8play_again;
			   u8 u8is_boost;
	}

	SC_REQ_DUNGEON_CREATE_SINGLE_V2      0x1137
	{
			   s16       ack;                                      /// 1:완료 , 1400: 전투 후유증, 3400: 스태미너 부족
	}
	 */

	PREPARE_PACKET;

	uint16_t dungeon_id = 0;
	uint8_t difficulty = 0;
	uint8_t play_again = 0;
	uint8_t isBooster = 0;

#define __PLAY_DUNGEON_AGAIN__ // 던전 다시 하기 기능 ON/OFF

#ifdef __PLAY_DUNGEON_AGAIN__
	*pPacket >> dungeon_id >> difficulty >> play_again >> isBooster;
#else
	*pPacket >> dungeon_id >> difficulty;
#endif

	// 보유 ZEN을 확인하여 Booster 사용 가능 여부 확인
	if (1 == isBooster)
	{
		NResource::VCResource::Flyweight * pFly =
				NResource::Static::InstancePtr()->GetVCRef()->GetFly(static_cast<int>(EM_VCINDEX_DUNGEON_BOOSTER));

		if (pUser->GetVirtualCurrency()->GetZen() < (pFly->_VC_PRICE * -1))
		{
			DEBUGLOG("%s : NOT ENOUGHT ZEN!!!", __FUNCTION__);
			SendAckDungeonCreateSingleV2(pUser, ACK_UNKNOWN_ERROR);
			return;
		}
	}


	if (difficulty < 0 || difficulty > 2)
	{
		DEBUGLOG("%s : INVALID DIFFICULTY!! difficulty=%d", __FUNCTION__, difficulty);
		SendAckDungeonCreateSingleV2(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NResource::DungeonData::Flyweight * pFly =
			NResource::Static::InstancePtr()->GetDungeon()->GetFly(pUser->GetCompany(), pUser->GetSaleCode(), dungeon_id);
	if (pFly == NULL)
	{
		DEBUGLOG("%s : pFly == NULL! dungeon_id=%d", __FUNCTION__, dungeon_id);
		SendAckDungeonCreateSingleV2(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	// _space는 현재 위치하고 있는 space를 나타낸다. 따라서 _world와 동일할 수도 있다.(동일하다면, 기존에 마을에 있었던 것이다.)
	// _world는 마을에 대한 space backup이다.
	NLogic::Space * pSpace = pUser->GetSpace();
	if (pSpace == NULL)
	{
		DEBUGLOG("%s : pSpace == NULL", __FUNCTION__);
		SendAckDungeonCreateSingleV2(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	if (false == pUser->EndBattle_afterEffect())
	{
		SendAckDungeonCreateSingleV2(pUser, ACK_BATTLE_AFTEREFFECT);
		return;
	}

	if ( 0 == play_again // 던전을 했던 경우에는 state가 SINGLE_DUNGEON/ENTER_EVENT_DUNGEON 이다. 따라서 '던전 다시하기' 기능에서는 하기 검사를 하면 안된다.
			&& pUser->GetEnumState() != User::EnumState::__NONE__
			&& pUser->GetEnumState() != User::EnumState::ENTER_EVENT_DUNGEON) // 이벤트 던전 상태도 빠져야 하는가?
	{
		DEBUGLOG("%s : pUser->GetEnumState() != User::EnumState::__NONE__", __FUNCTION__);
		SendAckDungeonCreateSingleV2(pUser, ACK_UNKNOWN_ERROR);
		return;
	}
	else if ( 1 == play_again
			&& !(pUser->GetEnumState() == User::EnumState::SINGLE_DUNGEON || pUser->GetEnumState() == User::EnumState::ENTER_EVENT_DUNGEON) )
	{
		DEBUGLOG("%s : pUser->GetEnumState() != User::EnumState::SINGLE_DUNGEON", __FUNCTION__);
		SendAckDungeonCreateSingleV2(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	// 스태미너 부족 여부 확인
	if (true == NResource::Static::Instance().GetContentsOpenResource()->IsOpen(ContentsOpen::STAMINA_SYSTEM))
	{
		// 이벤트 던전이 아닌 경우에만 체력치를 확인한다.
		if (8 != pFly->THEME)
		{
			NLogic::Stamina * pStamina = pUser->GetStamina();
			if (NULL == pStamina)
			{
				DEBUGLOG("%s : pStamina is NULL", __FUNCTION__);
				SendAckDungeonCreateSingleV2(pUser, ACK_UNKNOWN_ERROR);
				return;
			}

			if (true == pStamina->IsStaminaLack(difficulty))
			{
				SendAckDungeonCreateSingleV2(pUser, ACK_NOT_ENOUGHT_DUNGEON_STAMINA);
				return;
			}
		}
	}

	pSpace->LeaveUser(pUser);


	NLogic::Space::Data clsData;
	clsData._maxUser = 1;
	clsData._table_id = dungeon_id;
	clsData._difficulty = difficulty;
	clsData._spaceType = NLogic::Space::SpaceType::SINGLE_DUNGEION;
	clsData._bDungeonBooster = isBooster; // 던전 입장 시 부스터 사용 여부 저장	

	NLogic::Space * pSingleDungeon = NLogic::Static::Instance().GETSPACEPOOL()->NEW();
	pSingleDungeon->Open(pUser, clsData);


	pSingleDungeon->EnterUser(pUser);

	pUser->SetEnumState(User::EnumState::SINGLE_DUNGEON);

	SendAckDungeonCreateSingleV2(pUser, ACK_OK);
}

} /*NCommand*/ } /*ProjectZ*/
